package com.smt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.smt.common.PageBean;
import com.smt.entity.Classes;
import com.smt.entity.Student;
import com.smt.service.StudentService;
import com.smt.support.EsIndexConsist;
import com.smt.vo.StudentQuery;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.MultiSearchRequest;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @autor xiaoyu.fang
 * @date 2019/6/17 16:17
 */
@Slf4j
@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private RestHighLevelClient client;

    @Override
    public void insert(Student student) throws IOException {
        student.setId(UUID.randomUUID().toString());
        student.setCreateAt(new Date());
        IndexRequest indexRequest = new IndexRequest(EsIndexConsist.BUS_STUDENT_INDEX, EsIndexConsist.BUS_STUDENT_TYPE, student.getId());
        indexRequest.source(JSON.toJSONString(student), XContentType.JSON);
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        log.info("insert ====> {}", indexResponse);
    }

    @Override
    public void update(Student student) throws IOException {
        UpdateRequest updateRequest = new UpdateRequest(EsIndexConsist.BUS_STUDENT_INDEX, EsIndexConsist.BUS_STUDENT_TYPE, student.getId());
        updateRequest.doc(JSON.toJSONString(student), XContentType.JSON);
        UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
        log.info("update ======> {}", updateResponse);
    }

    @Override
    public void delete(String id) throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(EsIndexConsist.BUS_STUDENT_INDEX, EsIndexConsist.BUS_STUDENT_TYPE, id);
        DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
        log.info("delete =======> {}", deleteResponse);
    }

    @Override
    public Student findOne(String id) throws IOException {
        GetRequest getRequest = new GetRequest(EsIndexConsist.BUS_STUDENT_INDEX, EsIndexConsist.BUS_STUDENT_TYPE, id);
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        String json = JSON.toJSONString(getResponse.getSource());
        Student student = JSONObject.parseObject(json, Student.class);
        return student;
    }

    @Override
    public List<Student> query(String name, String identity, String address) throws IOException {
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        if (name != null) {
            // 名字查询
            boolBuilder.must(QueryBuilders.matchQuery("name", name));
        }
        if (identity != null) {
            // 精准查询
            boolBuilder.must(QueryBuilders.termQuery("identity", identity));
        }
        if (address != null) {
            // 地址查询
            boolBuilder.must(QueryBuilders.matchQuery("address", address));
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolBuilder);
        SearchRequest searchRequest = new SearchRequest(EsIndexConsist.BUS_STUDENT_INDEX);
        searchRequest.types(EsIndexConsist.BUS_STUDENT_TYPE);
        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = response.getHits();
        List<Student> studentList = new ArrayList<>();
        for (SearchHit searchHit : searchHits) {
            String source = searchHit.getSourceAsString();
            Student entity = JSONObject.parseObject(source, Student.class);
            entity.setId(searchHit.getId());
            studentList.add(entity);
        }
        return studentList;
    }

    @Override
    public PageBean<Student> page(StudentQuery query) throws IOException {
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        if (!StringUtils.isEmpty(query.getName())) {
            // 名字查询
            boolBuilder.must(QueryBuilders.matchQuery("name", query.getName()));
        }
        if (!StringUtils.isEmpty(query.getIdentity())) {
            // 精准查询
            boolBuilder.must(QueryBuilders.termQuery("identity", query.getIdentity()));
        }
        if (!StringUtils.isEmpty(query.getAddress())) {
            // 地址查询
            boolBuilder.must(QueryBuilders.matchQuery("address", query.getAddress()));
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolBuilder);
        sourceBuilder.from(query.getPageNum());
        sourceBuilder.size(query.getPageSize());
        SearchRequest searchRequest = new SearchRequest(EsIndexConsist.BUS_STUDENT_INDEX);
        searchRequest.types(EsIndexConsist.BUS_STUDENT_TYPE);
        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = response.getHits();
        List<Student> studentList = new ArrayList<>();
        for (SearchHit searchHit : searchHits) {
            String source = searchHit.getSourceAsString();
            Student entity = JSONObject.parseObject(source, Student.class);
            entity.setId(searchHit.getId());
            studentList.add(entity);
        }
        PageBean pageBean = new PageBean(query.getPageNum(), query.getPageSize(), searchHits.totalHits, studentList);
        return pageBean;
    }

    @Override
    public void joinquery() throws IOException {
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("classId", "JIJNZGsBiAP80X7OZAcZ"));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(boolBuilder);
        SearchRequest searchRequest = new SearchRequest(EsIndexConsist.BUS_STUDENT_INDEX);
        searchRequest.types(EsIndexConsist.BUS_STUDENT_TYPE);
        searchRequest.source(sourceBuilder);

        BoolQueryBuilder boolBuilder2 = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", "JIJNZGsBiAP80X7OZAcZ"));
        SearchSourceBuilder sourceBuilder2 = new SearchSourceBuilder().query(boolBuilder2);
        SearchRequest searchRequest2 = new SearchRequest("bus_class");
        searchRequest2.types("classes");
        searchRequest2.source(sourceBuilder2);
        MultiSearchRequest multiSearchRequest = new MultiSearchRequest();
        multiSearchRequest.add(searchRequest).add(searchRequest2);

        MultiSearchResponse response = client.msearch(multiSearchRequest, RequestOptions.DEFAULT);
        MultiSearchResponse.Item[] items = response.getResponses();
        SearchHits searchHits = items[0].getResponse().getHits();
        List<Student> studentList = new ArrayList<>();
        for (SearchHit searchHit : searchHits) {
            String source = searchHit.getSourceAsString();
            Student entity = JSONObject.parseObject(source, Student.class);
            entity.setId(searchHit.getId());
            studentList.add(entity);
        }
        String entity2 = items[1].getResponse().getHits().iterator().next().getSourceAsString();
        Classes classes = JSONObject.parseObject(entity2, Classes.class);
        log.info("students =========> {}, class ==========> {}", studentList.toString(), classes.toString());
    }

    /**
     * 创建索引
     * @param index
     * @throws IOException
     */
    @Override
    public void createIndex(String index) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(index);
        CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println("createIndex: " + JSON.toJSONString(createIndexResponse));
    }

    /**
     * 判断索引是否存在
     * @param index
     * @return
     * @throws IOException
     */
    @Override
    public boolean existsIndex(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest();
        request.indices(index);
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println("existsIndex: " + exists);
        return exists;
    }

}
